﻿package _Pan3D.core
{
	import _Pan3D.base.Camera3D;
	import _Pan3D.base.Object3D;
	import _Pan3D.base.ObjectMath;
// --------------MSN:lation_pan@live.cn  QQ: 3423526------------- //
	public class Calculation
	{

		public static function _DistPt2Panel(p:Object3D, E:ObjectMath):Number
		{
			return Math.abs(E.a * p.x + E.b * p.y + E.c * p.z + E.d) / Math.sqrt(E.a * E.a + E.b * E.b + E.c * E.c);
		}
		public static function _PanelEquationFromThreePt(p1:Object3D, p2:Object3D, p3:Object3D):ObjectMath
		{
			//得到平面方程 ax+by+cz+d=0(传入三个点,返回平面方程a,b,c,d);
			var a:Number=((p2.y - p1.y) * (p3.z - p1.z) - (p2.z - p1.z) * (p3.y - p1.y));
			var b:Number=((p2.z - p1.z) * (p3.x - p1.x) - (p2.x - p1.x) * (p3.z - p1.z));
			var c:Number=((p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x));
			var d:Number=(0 - (a * p1.x + b * p1.y + c * p1.z));
			var tempObjectMath:ObjectMath=new ObjectMath;
			tempObjectMath.a=a;
			tempObjectMath.b=b;
			tempObjectMath.c=c;
			tempObjectMath.d=d;
			return tempObjectMath;
		}
		public static function _anti_computing_point(_3dpoint:Object3D, _Cam:Camera3D):void
		{
			//这是一个相对于镜头坐标算出得到原来世界坐标。。在这个数里先不加上镜头的坐标系，只是算出他的相对镜头从头位移，
			//这个功能是为了方便移动场景。所要用到的，
			var rx:Number=_3dpoint.rx;
			var ry:Number=_3dpoint.ry;
			var rz:Number=_3dpoint.rz;
			
			var sin_y:Number=Math.sin(-_Cam.angle_y * Math.PI / 180);
			var cos_y:Number=Math.cos(-_Cam.angle_y * Math.PI / 180);
			var sin_x:Number=Math.sin(-_Cam.angle_x * Math.PI / 180);
			var cos_x:Number=Math.cos(-_Cam.angle_x * Math.PI / 180);
			
			
			var tmp_rz : Number = rz;
			rz = _Cam.cos_x * tmp_rz - _Cam.sin_x * ry;
			ry = _Cam.sin_x * tmp_rz + _Cam.cos_x * ry;
			
			var tmp_rx : Number = rx;
			rx = _Cam.cos_y * tmp_rx - _Cam.sin_y * rz;
			rz = _Cam.sin_y * tmp_rx + _Cam.cos_y * rz;
			
			_3dpoint.x=rx 
			_3dpoint.y=ry
			_3dpoint.z=rz 
		}
		public static function _anti_computing_point_copy(_3dpoint:Object3D, _Cam:Camera3D):void
		{
			
			var rx:Number=_3dpoint.rx;
			var ry:Number=_3dpoint.ry;
			var rz:Number=_3dpoint.rz;
			
			var sin_y:Number=Math.sin(-_Cam.angle_y * Math.PI / 180);
			var cos_y:Number=Math.cos(-_Cam.angle_y * Math.PI / 180);
			var sin_x:Number=Math.sin(-_Cam.angle_x * Math.PI / 180);
			var cos_x:Number=Math.cos(-_Cam.angle_x * Math.PI / 180);

			var tmp_rz : Number = rz;
			rz = _Cam.cos_x * tmp_rz - _Cam.sin_x * ry;
			ry = _Cam.sin_x * tmp_rz + _Cam.cos_x * ry;
			
			var tmp_rx : Number = rx;
			rx = _Cam.cos_y * tmp_rx - _Cam.sin_y * rz;
			rz = _Cam.sin_y * tmp_rx + _Cam.cos_y * rz;
			
			_3dpoint.x=(rx + _Cam.x);
			_3dpoint.y=(ry + _Cam.y);
			_3dpoint.z=(rz + _Cam.z);
		}

		public static function _get_hit_rec(a:Object3D, b:Object3D, c:Object3D, _Cam:Camera3D, xx:Number, yy:Number):Object3D
		{
			var A:Object3D=new Object3D();
			var B:Object3D=new Object3D();
			var C:Object3D=new Object3D();
			A.x=a.rx;
			A.y=a.ry;
			A.z=a.rz;
			B.x=b.rx;
			B.y=b.ry;
			B.z=b.rz;
			C.x=c.rx;
			C.y=c.ry;
			C.z=c.rz;
			var _obj:ObjectMath=_PanelEquationFromThreePt(A, B, C);
			var _D:Object3D=_math_intersect(_obj, _Cam, xx, yy);
			_anti_computing_point( _D,_Cam);
			return (_D);
		}

		public static function _math_intersect(_obj:ObjectMath, _Cam:Camera3D, xx:Number, yy:Number):Object3D
		{
			//这里是用屏幕的射线，为算出在这个镜头坐标系中，与原来设定的三个定形成的平面，的焦点。
			var a:Number=_obj.a;
			var b:Number=_obj.b;
			var c:Number=_obj.c;
			var d:Number=_obj.d;
			var n:Number = 1.8304877/2; //在这里，因为镜头的投影不是1.1/一个很神奇的数字，为了只是和屏幕尺寸对应
			var D:Object3D=new Object3D();
			var x2:Number=xx==0?1:xx/n;
			var y2:Number=yy==0?1:yy/n;
			var z2:Number=_Cam.fovw; //与屏幕焦点坐坐，方便对应鼠标的位置，用于算出射线与平面相交的点
			D.rx=-d / (a + (b * y2 / x2) + (c * z2 / x2));
			D.ry=D.rx / x2 * y2;
			D.rz=D.rx / x2 * z2;
			return D;
			//	(x-x1)/(x2-x1)=(y-y1)/(y2-y1)=(z-z1)/(z2-z1)  直线方程
			//   ax+by+cz+d=0;  平面方程;
		}
	}
}
